<template>
  <div class="full-calendar">
    <header v-if="header" class="picker">
      <el-date-picker
        v-model="currentDate"
        class="picker-date"
        :picker-options="{ firstDayOfWeek: 1 }"
        :format="type === 'week' ? 'yyyy第WW周' : 'yyyy年MM月dd日'"
        :type="type"
        :clearable="false"
        :editable="false"
      ></el-date-picker>
    </header>
    <full-calendar
      :id="id"
      ref="fullCalendar"
      v-loading="loading"
      :height="height"
      locale="zh-cn"
      default-view="resourceTimeGridDay"
      slot-duration="00:15"
      slot-label-interval="00:15"
      min-time="07:00"
      max-time="20:00"
      week-number-calculation="ISO"
      :all-day-slot="false"
      :nav-links="true"
      :event-limit="true"
      :editable="true"
      :header="header"
      :selectable="canAdd"
      :slot-label-format="eventFormat"
      :event-time-format="eventFormat"
      :button-text="buttonText"
      :custom-buttons="customButtons"
      :title-format="handleTitleChange"
      :plugins="plugins"
      :resources="resourcesFilterData"
      :resource-render="resourceRender"
      :events="eventsFilterData"
      @eventDrop="handleEventChange"
      @eventResize="handleEventChange"
      @select="handleAdd"
      @eventClick="handleEventClick"
      @datesRender="handleDatesRender"
      @eventRender="handleEventRender"
    />
  </div>
</template>

<script>
import dayjs from 'dayjs'
import FullCalendar from '@fullcalendar/vue'
import dayGridPlugin from '@fullcalendar/daygrid'
import timeGridPlugin from '@fullcalendar/timegrid'
import interactionPlugin from '@fullcalendar/interaction'
import resourceTimeGrid from '@fullcalendar/resource-timegrid'

export default {
  name: 'AppointmentTime',
  components: {
    FullCalendar,
  },
  props: {
    loading: {
      type: Boolean,
      default: false,
    },
    // 头部信息
    header: {
      type: Object,
      default: () => ({
        left: 'timeGridWeek,resourceTimeGridDay',
        center: 'prev,next',
        right: 'refresh,today',
      }),
    },
    // 标题
    resources: {
      type: Array,
      default: () => [],
    },
    // 数据
    events: {
      type: Array,
      default: () => [],
    },
  },
  data() {
    return {
      id: `fullCalendar-${+new Date()}`,
      type: 'date',
      plugins: [
        timeGridPlugin,
        interactionPlugin,
        dayGridPlugin,
        resourceTimeGrid,
      ],
      singleId: null,
      buttonText: {
        today: '今天',
        week: '周视图',
        day: '日视图',
      },
      eventFormat: {
        hour: '2-digit',
        minute: '2-digit',
        meridiem: false,
        hour12: false,
      },
      customButtons: {
        refresh: {
          text: '刷新',
          click: () => this.$emit('refresh'),
        },
      },
      currentDate: new Date(),
      todayDate: +new Date(new Date().toLocaleDateString()),
      canAdd: true,
      height: document.body.clientHeight - 166,
    }
  },
  computed: {
    resourcesFilterData() {
      if (this.loading) {
        return []
      }
      return this.resources.filter((i) =>
        this.singleId === null ? true : i.id == this.singleId
      )
    },
    eventsFilterData() {
      if (this.loading) {
        return []
      }
      return this.events.filter((i) =>
        this.singleId === null ? true : i.resourceId == this.singleId
      )
    },
  },
  watch: {
    currentDate(newVal, oldVal) {
      if (+newVal !== +oldVal) {
        this.gotoDate(newVal)
        this.$emit('date-change', this.type, this.currentDate)
      }
    },
    type(newVal, oldVal) {
      if (newVal !== oldVal) {
        this.$emit('date-change', this.type, this.currentDate)
      }
    },
  },
  mounted() {
    this.$nextTick(() => {
      console.log(this.getApi())
      setTimeout(() => this.getApi().refetchEvents(), 500)
    })
  },
  methods: {
    getApi(...arg) {
      return this.$refs.fullCalendar.getApi(...arg)
    },
    /**
     * 设置当前时间
     */
    gotoDate(date) {
      this.getApi().gotoDate(date)
    },
    scrollToTime(date) {
      this.getApi().scrollToTime(date)
    },
    /**
     * 格式化
     */
    handleTitleChange(e) {
      const { date, start, end } = e
      const startDate = dayjs(start.marker).format('YYYY-MM-DD')
      const endDate = dayjs(end.marker).subtract(1, 'day').format('YYYY-MM-DD')
      const eq = startDate === endDate

      this.type = eq ? 'date' : 'week'
      this.canAdd = eq && +this.todayDate <= +date.marker
      this.currentDate = date.marker
    },
    /**
     * 监听 resource 的点击
     */
    resourceRender(e) {
      e.el.addEventListener('click', () => {
        this.singleId = this.singleId === null ? e.resource.id : null
      })
    },
    handleAdd(e) {
      const { start, end } = e

      if ((+end - +start) / 60000 === 15) {
        return
      }

      this.$emit('add', e)
    },
    handleEventChange(...arg) {
      this.$emit('event-change', ...arg)
    },
    handleEventClick(...arg) {
      this.$emit('event-click', ...arg)
    },
    handleDatesRender(...arg) {
      this.$emit('dates-render', ...arg)
    },
    handleEventRender(...arg) {
      this.$emit('events-render', ...arg)
    },
  },
}
</script>

<style>
@import '~@fullcalendar/core/main.css';
@import '~@fullcalendar/daygrid/main.css';
@import '~@fullcalendar/timegrid/main.css';

.full-calendar {
  width: 100%;
  position: relative;
  background-color: #ffffff;
}

.picker {
  height: 30px;
  position: absolute;
  top: 18px;
  left: 50%;
  z-index: 1;
  transform: translateX(-50%);
}

.el-input--medium .el-input__inner,
.el-input--medium .el-input__icon {
  height: 30px;
  line-height: 30px;
}

.fc-toolbar.fc-header-toolbar {
  padding-top: 1.1em !important;
}

.fc-button-primary {
  padding: 0 8px;
  height: 30px;
  margin: 0 8px;
  color: #1e6ceb;
  border-radius: 0;
  border: 1px solid #1e6ceb;
  background-color: #ffffff;
}

.fc-button-primary:not(:disabled):active,
.fc-button-primary:not(:disabled).fc-button-active,
.fc-button-primary:hover,
.fc-button-primary:hover,
.fc-button-primary:disabled {
  color: #ffffff;
  border: 1px solid #1e6ceb;
  background-color: #1e6ceb;
}

.fc-prev-button,
.fc-next-button,
.fc-prev-button:hover,
.fc-next-button:hover {
  width: 30px;
  height: 30px;
  margin: 0 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #1e6ceb;
  border-radius: 0;
  border: 1px solid #1e6ceb;
  background-color: #ffffff !important;
  border-radius: 50%;
}

.fc-prev-button:active,
.fc-next-button:active {
  color: #1e6ceb !important;
}

.fc-button-primary:active,
.fc-button-primary:active,
.fc-prev-button:active,
.fc-next-button:active {
  box-shadow: 0 0 0 0.2rem #1e6ceb !important;
}

.fc-resource-cell {
  color: #1e6ceb !important;
}

.fc-prev-button,
.fc-next-button {
  position: relative;
  border-radius: 50% !important;
}

.fc-prev-button {
  left: -130px;
}

.fc-next-button {
  right: -100px;
}

.fc-event {
  position: relative;
  margin-left: 8px;
  padding: 5px;
  display: block;
  font-size: 16px;
  line-height: 24px;
  border-radius: 0px;
  background-color: #1e6ceb;
  border: none;
}

.fc-event:hover {
  opacity: 0.9;
  box-shadow: 0 0 3px 3px #eeeeee;
}

.fc-icon {
  display: inline-block;
  width: 1em !important;
  height: 1em !important;
  text-align: center !important;
  margin-left: -2px !important;
  margin-top: -2px !important;
}

.fc-time-grid .fc-slats td {
  height: 1.9em !important;
  border-bottom: 0 !important;
}

.fc th,
.fc td {
  border-style: solid !important;
  border-width: 1px !important;
  padding: 0 !important;
  vertical-align: top !important;
  height: 30px !important;
  /* margin-top:5px !important; */
}

.fc .fc-axis {
  vertical-align: middle !important;
  padding: 0 4px !important;
  white-space: nowrap !important;
  color: #666666 !important;
}

.fc th,
.fc td .fc-day-header {
  border-style: solid !important;
  border-width: 1px !important;
  padding: 0 !important;
  vertical-align: middle !important;
  color: #333333;
  font-weight: normal !important;
}

.fc th,
.fc td .fc-widget-content {
  height: 30px !important;
}

.fc-toolbar .fc-header-toolbar .fc-center .h2 {
  font-size: 14px !important;
}

.fc-toolbar.fc-header-toolbar {
  margin-bottom: 1.1em !important;
}

.fc-widget-header .fc-today {
  color: #1e6ceb !important;
}

.fc-unthemed td.fc-today {
  background: #ffffff !important;
}

.fc .fc-row {
  border-style: solid;
  border-width: 0;
  background-color: #eaf2f8;
}

.fc-license-message {
  z-index: -1000 !important;
}
</style>
